#include <iostream>
#include<stdio.h>
#include<time.h>
#include <arm_neon.h> //需包含的头文件
using namespace std;
const int N=300;
void LU(float **m,int n){
    for(int k=0;k<n;k++){
        for(int j=k+1;j<n;j++){
            m[k][j]/=m[k][k];
        }
        m[k][k]=1.0;
        for(int i=k+1;i<n;i++){
                for(int j=k+1;j<n;j++){
                        m[i][j]=m[i][j]-m[i][j]*m[k][j];
        }
        m[i][k]=0;
        }
}
}
void SIMD_Neon(float **m,int N){
 for(int k=0;k<N;k++){
        float32x4_t vt=vld1q_f32(&m[k][k]);
        for(int j=k+1;j<N-3;j+=4){
            float32x4_t va=vld1q_f32(&m[k][j]);
            va=vdivq_f32(va, vt);
            vst1q_f32(&m[k][j],va);
        }
        for(int j=N-3;j<N;j++)
            m[k][j]=m[k][j]/m[k][k];
        m[k][k]=1.0;
        for(int i=k+1;i<N;i++){
            float32x4_t vaik=vld1q_f32(&m[i][k]);
             for(int j=k+1;j<N-3;j+=4){
                 float32x4_t vakj=vld1q_f32(&m[k][j]);
                 float32x4_t vaij=vld1q_f32(&m[i][j]);
                 float32x4_t vx=vakj*vaij;
                 vaij-=vx;
                 vst1q_f32(&m[i][j],vaij);
             }
             for(int j=k+1;j<N-3;j+=4){
                 m[i][j]=m[i][j]-m[k][j]*m[i][k];
             }
             m[i][k]=0;
        }
    }
}
int main(){
    float **m=new float*[N];
    for(int i=0;i<N;i++)
      m[i]=new float[N];
    for(int i=0;i<N;i++){
        for(int j=0;j<N;j++)
            m[i][j]=rand()%100;
    }


    struct timespec sts,ets;
    timespec_get(&sts,TIME_UTC);
    LU(m,N);
    timespec_get(&ets,TIME_UTC);
    time_t dsec=ets.tv_sec-sts.tv_sec;
    long dnsec=ets.tv_nsec-sts.tv_nsec;
    if (dnsec<0){
             dsec--;
    dnsec+=1000000000ll;
    }
    cout<<"BEFORE";
    printf ("%lld.%09llds\n",dsec,dnsec);
    
    for(int i=0;i<N;i++){
        for(int j=0;j<N;j++)
            m[i][j]=rand()%100;
    }
    timespec_get(&sts,TIME_UTC);

    SIMD_Neon(m,N);
    timespec_get(&ets,TIME_UTC);
    dsec=ets.tv_sec-sts.tv_sec;
    dnsec=ets.tv_nsec-sts.tv_nsec;
    if (dnsec<0){
             dsec--;
    dnsec+=1000000000ll;
    }
    cout<<"AFTER:";
    printf ("%lld.%09llds\n",dsec,dnsec);

}
